// 2010年版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

// Package cipher实现可包装的标准分组密码模式
// 关于低级分组密码实现。
// 请参阅https:
// 以及NIST特别出版物800-38A。
package cipher

// 块表示块密码的实现
// 使用给定的键。它提供了加密功能
// 或者对单个块进行解密。模式实现
// 将该功能扩展到块流。
type Block interface {
	// BlockSize返回密码的块大小。
	BlockSize() int

	// Encrypt将src中的第一个块加密到dst中。
	// Dst和src必须完全重叠或完全不重叠。
	Encrypt(dst, src []byte)

	// 解密将src中的第一个块解密为dst。
	// Dst和src必须完全重叠或完全不重叠。
	Decrypt(dst, src []byte)
}

// 流表示流密码。
type Stream interface {
	// XORKeyStream将给定片中的每个字节与来自
	// 密码的密钥流。Dst和src必须完全重叠或完全不重叠。
	// None
	// 如果len（dst）<len（src），XORKeyStream应该死机。这是可以接受的
	// 通过比src大的dst，在这种情况下，XORKeyStream将
	// 仅更新dst[：len（src）]，不会接触dst的其余部分。
	// None
	// 对XORKeyStream的多个调用的行为就像
	// src缓冲区在一次运行中传递。也就是说，流
	// 保持状态，不会在每次XORKeyStream调用时重置。
	XORKeyStream(dst, src []byte)
}

// 块模式表示以基于块的模式（CBC）运行的块密码，
// 欧洲央行等）。
type BlockMode interface {
	// BlockSize返回模式的块大小。
	BlockSize() int

	// CryptBlocks加密或解密许多块。长度
	// src必须是块大小的倍数。Dst和src必须重叠
	// 完全或完全没有。
	// None
	// 如果len（dst）<len（src），CryptBlocks应该死机。这是可以接受的
	// 通过比src大的dst，在这种情况下，CryptBlocks将
	// 仅更新dst[：len（src）]，不会接触dst的其余部分。
	// None
	// 对CryptBlock的多个调用的行为就像
	// src缓冲区在一次运行中传递。即块模式
	// 保持状态，并且不会在每次CryptBlocks调用时重置。
	CryptBlocks(dst, src []byte)
}

// 实用程序例程

func dup(p []byte) []byte {
	q := make([]byte, len(p))
	copy(q, p)
	return q
}
